home *** CD-ROM | disk | FTP | other *** search
/ Suzy B Software 2 / Suzy B Software CD-ROM 2 (1994).iso / new_file / mintprgs / mint112s / mint112s.lzh / dos.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-14  |  20.3 KB  |  929 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992,1993,1994 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /* miscellaneous DOS functions, and the DOS initialization function */
  8.  
  9. #include "mint.h"
  10.  
  11. #define DOS_MAX 0x160
  12.  
  13. Func dos_tab[DOS_MAX];
  14. short dos_max = DOS_MAX;
  15.  
  16. static void alarmme P_((PROC *));
  17. static void itimer_real_me P_((PROC *p));
  18. static void itimer_virtual_me P_((PROC *p));
  19. static void itimer_prof_me P_((PROC *p));
  20.  
  21. long ARGS_ON_STACK 
  22. s_version()
  23. {
  24.     return Sversion();
  25. }
  26.  
  27. /*
  28.  * Super(new_ssp): change to supervisor mode.
  29.  */
  30.  
  31. long ARGS_ON_STACK
  32. s_uper(new_ssp)
  33.     long new_ssp;
  34. {
  35.     int in_super;
  36.     long r;
  37.  
  38.     TRACE(("Super"));
  39.     in_super = curproc->ctxt[SYSCALL].sr & 0x2000;
  40.  
  41.     if (new_ssp == 1) {
  42.         r = in_super ? -1L : 0;
  43.     }
  44.     else {
  45.         curproc->ctxt[SYSCALL].sr ^= 0x2000;
  46.         r = curproc->ctxt[SYSCALL].ssp;
  47.         if (in_super) {
  48.             if (new_ssp == 0) {
  49.                 DEBUG(("bad Super call"));
  50.                 raise(SIGSYS);
  51.             }
  52.             else {
  53.                 curproc->ctxt[SYSCALL].usp = 
  54.                     curproc->ctxt[SYSCALL].ssp;
  55.                 curproc->ctxt[SYSCALL].ssp = new_ssp;
  56.             }
  57.         }
  58.         else {
  59.             curproc->ctxt[SYSCALL].ssp = 
  60.                 new_ssp ? new_ssp : curproc->ctxt[SYSCALL].usp;
  61.         }
  62.     }
  63.     return r;
  64. }
  65.  
  66. /*
  67.  * get/set time and date functions
  68.  */
  69. long ARGS_ON_STACK t_getdate() { return datestamp; }
  70. long ARGS_ON_STACK t_gettime() { return timestamp; }
  71.  
  72. long ARGS_ON_STACK t_setdate(date)
  73.     int date;
  74. {
  75.     long r;
  76.  
  77. /* Only the superuser may set date or time */
  78.     if (curproc->euid != 0)
  79.         return EACCDN;
  80.     r = Tsetdate(date);
  81.     datestamp = Tgetdate();
  82.     return r;
  83. }
  84.  
  85. long ARGS_ON_STACK t_settime(time)
  86.     int time;
  87. {
  88.     long r;
  89.  
  90.     if (curproc->euid != 0)
  91.         return EACCDN;
  92.     r = Tsettime(time);
  93.     timestamp = Tgettime();
  94.     return r;
  95. }
  96.  
  97. /*
  98.  * GEMDOS extension: Syield(): give up the processor if any other
  99.  * processes are waiting. Always returns 0.
  100.  */
  101.  
  102. long ARGS_ON_STACK
  103. s_yield()
  104. {
  105. /* reward the nice process */
  106.     curproc->curpri = curproc->pri;
  107.     sleep(READY_Q, curproc->wait_cond);
  108.     return 0;
  109. }
  110.  
  111. /*
  112.  * GEMDOS extension:
  113.  * Prenice(pid, delta) sets the process priority level for process pid.
  114.  * A "nice" value < 0 increases priority, one > 0 decreases it.
  115.  * Always returns the new priority (so Prenice(pid, 0) queries the current
  116.  * priority).
  117.  *
  118.  * NOTE: for backward compatibility, Pnice(delta) is provided and is equivalent
  119.  * to Prenice(Pgetpid(), delta)
  120.  */
  121.  
  122. long ARGS_ON_STACK
  123. p_renice(pid, delta)
  124.     int pid, delta;
  125. {
  126.     PROC *p;
  127.  
  128.     if (pid <= 0 || 0 == (p = pid2proc(pid))) {
  129.         return EFILNF;
  130.     }
  131.  
  132.     if (curproc->euid && curproc->euid != p->ruid
  133.         && curproc->ruid != p->ruid) {
  134.         DEBUG(("Prenice: process ownership error"));
  135.         return EACCDN;
  136.     }
  137.     p->pri -= delta;
  138.     if (p->pri < MIN_NICE) p->pri = MIN_NICE;
  139.     if (p->pri > MAX_NICE) p->pri = MAX_NICE;
  140.     p->curpri = p->pri;
  141.     return ((long)p->pri) & 0x0ffff;
  142. }
  143.  
  144. long ARGS_ON_STACK
  145. p_nice(delta)
  146.     int delta;
  147. {
  148.     return p_renice(curproc->pid,delta);
  149. }
  150.  
  151. /*
  152.  * GEMDOS extensions: routines for getting/setting process i.d.'s and
  153.  * user i.d.'s
  154.  */
  155.  
  156. long ARGS_ON_STACK p_getpid() { return curproc->pid; }
  157.  
  158. long ARGS_ON_STACK p_getppid() { return curproc->ppid; }
  159.  
  160. long ARGS_ON_STACK p_getpgrp() { return curproc->pgrp; }
  161.  
  162. /* note: Psetpgrp(0, ...) is equivalent to Psetpgrp(Pgetpid(), ...) */
  163. /* also note: Psetpgrp(x, 0) is equivalent to Psetpgrp(x, x) */
  164.  
  165. long ARGS_ON_STACK p_setpgrp(pid, newgrp)
  166.     int pid, newgrp;
  167. {
  168.     PROC *p;
  169.  
  170.     if (pid == 0)
  171.         p = curproc;
  172.     else if (0 == (p = pid2proc(pid)))
  173.         return EFILNF;
  174.     if ( (curproc->euid) && (p->ruid != curproc->ruid)
  175.           && (p->ppid != curproc->pid) )
  176.         return EACCDN;
  177.  
  178.     if (newgrp < 0)
  179.         return p->pgrp;
  180.  
  181.     if (newgrp == 0)
  182.         newgrp = p->pid;
  183.  
  184.     return (p->pgrp = newgrp);
  185. }
  186.  
  187. long ARGS_ON_STACK p_getuid() { return curproc->ruid; }
  188. long ARGS_ON_STACK p_getgid() { return curproc->rgid; }
  189. long ARGS_ON_STACK p_geteuid() { return curproc->euid; }
  190. long ARGS_ON_STACK p_getegid() { return curproc->egid; }
  191.  
  192. long ARGS_ON_STACK
  193. p_setuid(id)
  194.     int id;
  195. {
  196.     if (curproc->euid == 0 || curproc->euid == id || curproc->ruid == id) {
  197.         curproc->ruid = curproc->euid = id;
  198.         return id;
  199.     }
  200.     return EACCDN;
  201. }
  202.  
  203. long ARGS_ON_STACK
  204. p_setgid(id)
  205.     int id;
  206. {
  207.     if (curproc->euid == 0 || curproc->rgid == id) {
  208.         curproc->egid = curproc->rgid = id;
  209.         return id;
  210.     }
  211.     return EACCDN;
  212. }
  213.  
  214. /* uk: set effective uid/gid but leave the real uid/gid unchanged. */
  215. long ARGS_ON_STACK
  216. p_seteuid(id)
  217.     int id;
  218. {
  219.     if (curproc->euid == 0 || curproc->ruid    == id) {
  220.         curproc->euid = id;
  221.         return id;
  222.     }
  223.     return EACCDN;
  224. }
  225.     
  226. long ARGS_ON_STACK
  227. p_setegid(id)
  228.     int id;
  229. {
  230.     if (curproc->euid == 0 || curproc->egid == 0 || curproc->rgid == id) {
  231.         curproc->egid = id;
  232.         return id;
  233.     }
  234.     return EACCDN;
  235. }
  236.  
  237. /*  tesche: audit user id functions, these id's never change once set to != 0
  238.  * and can therefore be used to determine who the initially logged in user was.
  239.  */
  240. long ARGS_ON_STACK
  241. p_getauid()
  242. {
  243.     return curproc->auid;
  244. }
  245.  
  246. long ARGS_ON_STACK
  247. p_setauid(id)
  248.     int id;
  249. {
  250.     if (curproc->auid)
  251.         return EACCDN;    /* this may only be changed once */
  252.  
  253.     return (curproc->auid = id);
  254. }
  255.  
  256. /*  tesche: get/set supplemantary group id's.
  257.  */
  258. long ARGS_ON_STACK
  259. p_getgroups(gidsetlen, gidset)
  260.     int gidsetlen;
  261.     int gidset[];
  262. {
  263.     int i;
  264.  
  265.     if (gidsetlen == 0)
  266.         return curproc->ngroups;
  267.  
  268.     if (gidsetlen < curproc->ngroups)
  269.         return ERANGE;
  270.  
  271.     for (i=0; i<curproc->ngroups; i++)
  272.         gidset[i] = curproc->ngroup[i];
  273.  
  274.     return curproc->ngroups;
  275. }
  276.  
  277. long ARGS_ON_STACK
  278. p_setgroups(ngroups, gidset)
  279.     int ngroups;
  280.     int gidset[];
  281. {
  282.     int i;
  283.  
  284.     if (curproc->euid)
  285.         return EACCDN;    /* only superuser may change this */
  286.  
  287.     if ((ngroups < 0) || (ngroups > NGROUPS_MAX))
  288.         return ERANGE;
  289.  
  290.     curproc->ngroups = ngroups;
  291.     for (i=0; i<ngroups; i++)
  292.         curproc->ngroup[i] = gidset[i];
  293.  
  294.     return ngroups;
  295. }
  296.  
  297. /*
  298.  * a way to get/set process-specific user information. the user information
  299.  * longword is set to "arg", unless arg is -1. In any case, the old
  300.  * value of the longword is returned.
  301.  */
  302.  
  303. long ARGS_ON_STACK
  304. p_usrval(arg)
  305.     long arg;
  306. {
  307.     long r;
  308.  
  309.     TRACE(("Pusrval"));
  310.     r = curproc->usrdata;
  311.     if (arg != -1L)
  312.         curproc->usrdata = arg;
  313.     return r;
  314. }
  315.  
  316. /*
  317.  * set the file creation mask to "mode". Returns the old value of the
  318.  * mask.
  319.  */
  320. long ARGS_ON_STACK p_umask(mode)
  321.     unsigned mode;
  322. {
  323.     long oldmask = curproc->umask;
  324.  
  325.     curproc->umask = mode & (~S_IFMT);
  326.     return oldmask;
  327. }
  328.  
  329. /*
  330.  * get/set the domain of a process. domain 0 is the default (TOS) domain.
  331.  * domain 1 is the MiNT domain. for now, domain affects read/write system
  332.  * calls and filename translation.
  333.  */
  334.  
  335. long ARGS_ON_STACK
  336. p_domain(arg)
  337.     int arg;
  338. {
  339.     long r;
  340.     TRACE(("Pdomain(%d)", arg));
  341.  
  342.     r = curproc->domain;
  343.     if (arg >= 0)
  344.         curproc->domain = arg;
  345.     return r;
  346. }
  347.  
  348. /*
  349.  * get process resource usage. 8 longwords are returned, as follows:
  350.  *     r[0] == system time used by process
  351.  *     r[1] == user time used by process
  352.  *     r[2] == system time used by process' children
  353.  *     r[3] == user time used by process' children
  354.  *     r[4] == memory used by process
  355.  *     r[5] - r[7]: reserved for future use
  356.  */
  357.  
  358. long ARGS_ON_STACK
  359. p_rusage(r)
  360.     long *r;
  361. {
  362.     r[0] = curproc->systime;
  363.     r[1] = curproc->usrtime;
  364.     r[2] = curproc->chldstime;
  365.     r[3] = curproc->chldutime;
  366.     r[4] = memused(curproc);
  367.     return 0;
  368. }
  369.  
  370. /*
  371.  * get/set resource limits i to value v. The old limit is always returned;
  372.  * if v == -1, the limit is unchanged, otherwise it is set to v. Possible
  373.  * values for i are:
  374.  *    1:  max. cpu time    (milliseconds)
  375.  *    2:  max. core memory allowed
  376.  *    3:  max. amount of malloc'd memory allowed
  377.  */
  378. long ARGS_ON_STACK
  379. p_setlimit(i, v)
  380.     int i;
  381.     long v;
  382. {
  383.     long oldlimit;
  384.  
  385.     switch(i) {
  386.     case 1:
  387.         oldlimit = curproc->maxcpu;
  388.         if (v >= 0) curproc->maxcpu = v;
  389.         break;
  390.     case 2:
  391.         oldlimit = curproc->maxcore;
  392.         if (v >= 0) {
  393.             curproc->maxcore = v;
  394.             recalc_maxmem(curproc);
  395.         }
  396.         break;
  397.     case 3:
  398.         oldlimit = curproc->maxdata;
  399.         if (v >= 0) {
  400.             curproc->maxdata = v;
  401.             recalc_maxmem(curproc);
  402.         }
  403.         break;
  404.     default:
  405.         DEBUG(("Psetlimit: invalid mode %d", i));
  406.         return EINVFN;
  407.     }
  408.     TRACE(("p_setlimit(%d, %ld): oldlimit = %ld", i, v, oldlimit));
  409.     return oldlimit;
  410. }
  411.  
  412. /*
  413.  * pause: just sleeps on IO_Q, with wait_cond == -1. only a signal will
  414.  * wake us up
  415.  */
  416.  
  417. long ARGS_ON_STACK
  418. p_pause()
  419. {
  420.     TRACE(("Pause"));
  421.     sleep(IO_Q, -1L);
  422.     return 0;
  423. }
  424.  
  425. /*
  426.  * helper function for t_alarm: this will be called when the timer goes
  427.  * off, and raises SIGALRM
  428.  */
  429.  
  430. static void
  431. alarmme(p)
  432.     PROC *p;
  433. {
  434.     p->alarmtim = 0;
  435.     post_sig(p, SIGALRM);
  436. }
  437.  
  438. /*
  439.  * t_alarm(x): set the alarm clock to go off in "x" seconds. returns the
  440.  * old value of the alarm clock
  441.  */
  442.  
  443. long ARGS_ON_STACK
  444. t_alarm(x)
  445.     long x;
  446. {
  447.     long oldalarm;
  448.     oldalarm = t_malarm(x*1000);
  449.     oldalarm = (oldalarm+999)/1000;        /* convert to seconds */
  450.     return oldalarm;
  451. }
  452.  
  453. /*
  454.  * t_malarm(x): set the alarm clock to go off in "x" milliseconds. returns
  455.  * the old value ofthe alarm clock
  456.  */
  457.  
  458. long ARGS_ON_STACK
  459. t_malarm(x)
  460.     long x;
  461. {
  462.     long oldalarm;
  463.     TIMEOUT *t;
  464.  
  465. /* see how many milliseconds there were to the alarm timeout */
  466.     oldalarm = 0;
  467.  
  468.     if (curproc->alarmtim) {
  469.         for (t = tlist; t; t = t->next) {
  470.             oldalarm += t->when;
  471.             if (t == curproc->alarmtim)
  472.                 goto foundalarm;
  473.         }
  474.         DEBUG(("Talarm: old alarm not found!"));
  475.         oldalarm = 0;
  476.         curproc->alarmtim = 0;
  477. foundalarm:
  478.         ;
  479.     }
  480.  
  481. /* we were just querying the alarm */
  482.     if (x < 0)
  483.         return oldalarm;
  484.  
  485. /* cancel old alarm */
  486.     if (curproc->alarmtim)
  487.         canceltimeout(curproc->alarmtim);
  488.  
  489. /* add a new alarm, to occur in x milliseconds */
  490.     if (x)
  491.         curproc->alarmtim = addtimeout(x, alarmme);
  492.     else
  493.         curproc->alarmtim = 0;
  494.  
  495.     return oldalarm;
  496. }
  497.  
  498. #define ITIMER_REAL 0
  499. #define ITIMER_VIRTUAL 1
  500. #define ITIMER_PROF 2
  501.  
  502. /*
  503.  * helper function for t_setitimer: this will be called when the ITIMER_REAL
  504.  * timer goes off
  505.  */
  506.  
  507. static void
  508. itimer_real_me(p)
  509.     PROC *p;
  510. {
  511.     PROC *real_curproc;
  512.  
  513.     real_curproc = curproc;
  514.     curproc = p;
  515.     if (p->itimer[ITIMER_REAL].interval)
  516.       p->itimer[ITIMER_REAL].timeout =
  517.         addtimeout(p->itimer[ITIMER_REAL].interval, itimer_real_me);
  518.     else
  519.       p->itimer[ITIMER_REAL].timeout = 0;
  520.  
  521.     curproc = real_curproc;
  522.     post_sig(p, SIGALRM);
  523. }
  524.  
  525. /*
  526.  * helper function for t_setitimer: this will be called when the ITIMER_VIRTUAL
  527.  * timer goes off
  528.  */
  529.  
  530. static void
  531. itimer_virtual_me(p)
  532.     PROC *p;
  533. {
  534.     PROC *real_curproc;
  535.     long timeleft;
  536.  
  537.     real_curproc = curproc;
  538.     curproc = p;
  539.     timeleft = p->itimer[ITIMER_VIRTUAL].reqtime
  540.             - (p->systime - p->itimer[ITIMER_VIRTUAL].startsystime);
  541.     if (timeleft > 0) {
  542.         p->itimer[ITIMER_VIRTUAL].timeout =
  543.             addtimeout(timeleft, itimer_virtual_me);
  544.     } else {
  545.         timeleft = p->itimer[ITIMER_VIRTUAL].interval;
  546.         if (timeleft == 0) {
  547.             p->itimer[ITIMER_VIRTUAL].timeout = 0;
  548.         } else {
  549.             p->itimer[ITIMER_VIRTUAL].reqtime = timeleft;
  550.             p->itimer[ITIMER_VIRTUAL].startsystime = p->systime;
  551.             p->itimer[ITIMER_VIRTUAL].startusrtime = p->usrtime;
  552.             p->itimer[ITIMER_VIRTUAL].timeout =
  553.                 addtimeout(timeleft, itimer_virtual_me);
  554.         }
  555.         post_sig(p, SIGVTALRM);
  556.     }
  557.     curproc = real_curproc;
  558. }
  559.  
  560. /*
  561.  * helper function for t_setitimer: this will be called when the ITIMER_PROF
  562.  * timer goes off
  563.  */
  564.  
  565. static void
  566. itimer_prof_me(p)
  567.     PROC *p;
  568. {
  569.     PROC *real_curproc;
  570.     long timeleft;
  571.  
  572.     real_curproc = curproc;
  573.     curproc = p;
  574.     timeleft = p->itimer[ITIMER_PROF].reqtime
  575.             - (p->usrtime - p->itimer[ITIMER_PROF].startusrtime);
  576.     if (timeleft > 0) {
  577.         p->itimer[ITIMER_PROF].timeout =
  578.             addtimeout(timeleft, itimer_prof_me);
  579.     } else {
  580.         timeleft = p->itimer[ITIMER_PROF].interval;
  581.         if (timeleft == 0) {
  582.             p->itimer[ITIMER_PROF].timeout = 0;
  583.         } else {
  584.             p->itimer[ITIMER_PROF].reqtime = timeleft;
  585.             p->itimer[ITIMER_PROF].startsystime = p->systime;
  586.             p->itimer[ITIMER_PROF].startusrtime = p->usrtime;
  587.             p->itimer[ITIMER_PROF].timeout =
  588.                 addtimeout(timeleft, itimer_prof_me);
  589.         }
  590.         post_sig(p, SIGPROF);
  591.     }
  592.     curproc = real_curproc;
  593. }
  594.  
  595. /*
  596.  * t_setitimer(which, interval, value, ointerval, ovalue):
  597.  * schedule an interval timer
  598.  * which is ITIMER_REAL (0) for SIGALRM, ITIMER_VIRTUAL (1) for SIGVTALRM,
  599.  * or ITIMER_PROF (2) for SIGPROF.
  600.  * the rest of the parameters are pointers to millisecond values.
  601.  * interval is the value to which the timer will be reset
  602.  * value is the current timer value
  603.  * ointerval and ovalue are the previous values
  604.  */
  605.  
  606. long ARGS_ON_STACK
  607. t_setitimer(which, interval, value, ointerval, ovalue)
  608.     int which;
  609.     long *interval;
  610.     long *value;
  611.     long *ointerval;
  612.     long *ovalue;
  613. {
  614.     long oldtimer;
  615.     TIMEOUT *t;
  616.     void (*handler)() = 0;
  617.     long tmpold;
  618.  
  619.     if ((which != ITIMER_REAL) && (which != ITIMER_VIRTUAL)
  620.         && (which != ITIMER_PROF)) {
  621.             return EINVFN;
  622.     }
  623.  
  624. /* ensure that any addresses specified by the calling process are in that
  625.    process's address space
  626. */
  627.     if ((interval && (!(valid_address((long) interval))))
  628.         || (value && (!(valid_address((long) value))))
  629.         || (ointerval && (!(valid_address((long) ointerval))))
  630.         || (ovalue && (!(valid_address((long) ovalue))))) {
  631.             return EIMBA;
  632.     }
  633.  
  634. /* see how many milliseconds there were to the timeout */
  635.     oldtimer = 0;
  636.  
  637.     if (curproc->itimer[which].timeout) {
  638.         for (t = tlist; t; t = t->next) {
  639.             oldtimer += t->when;
  640.             if (t == curproc->itimer[which].timeout)
  641.                 goto foundtimer;
  642.         }
  643.         DEBUG(("Tsetitimer: old timer not found!"));
  644.         oldtimer = 0;
  645. foundtimer:
  646.         ;
  647.     }
  648.  
  649.     if (ointerval)
  650.         *ointerval = curproc->itimer[which].interval;
  651.     if (ovalue) {
  652.         if (which == ITIMER_REAL) {
  653.             *ovalue = oldtimer;
  654.         } else {
  655.           tmpold = curproc->itimer[which].reqtime
  656.             - (curproc->systime - curproc->itimer[which].startusrtime);
  657.           if (which == ITIMER_PROF)
  658.             tmpold -=
  659.               (curproc->systime - curproc->itimer[which].startsystime);
  660.           if (tmpold <= 0)
  661.             tmpold = 0;
  662.           *ovalue = tmpold;
  663.         }
  664.     }
  665.     if (interval)
  666.         curproc->itimer[which].interval = *interval;
  667.     if (value) {
  668. /* cancel old timer */
  669.         if (curproc->itimer[which].timeout)
  670.             canceltimeout(curproc->itimer[which].timeout);
  671.         curproc->itimer[which].timeout = 0;
  672.  
  673. /* add a new timer, to occur in x milliseconds */
  674.         if (*value) {
  675.             curproc->itimer[which].reqtime = *value;
  676.             curproc->itimer[which].startsystime =
  677.                 curproc->systime;
  678.             curproc->itimer[which].startusrtime =
  679.                 curproc->usrtime;
  680.             switch (which) {
  681.                 case ITIMER_REAL:
  682.                     handler = itimer_real_me;
  683.                     break;
  684.                 case ITIMER_VIRTUAL:
  685.                     handler = itimer_virtual_me;
  686.                     break;
  687.                 case ITIMER_PROF:
  688.                     handler = itimer_prof_me;
  689.                     break;
  690.                 default:
  691.                     break;
  692.             }
  693.             curproc->itimer[which].timeout =
  694.                 addtimeout(*value, handler);
  695.         }
  696.         else
  697.             curproc->itimer[which].timeout = 0;
  698.     }
  699.     return 0;
  700. }
  701.  
  702. /*
  703.  * sysconf(which): returns information about system configuration.
  704.  * "which" specifies which aspect of the system configuration is to
  705.  * be returned:
  706.  *    -1    max. value of "which" allowed
  707.  *    0    max. number of memory regions per proc
  708.  *    1    max. length of Pexec() execution string {ARG_MAX}
  709.  *    2    max. number of open files per process    {OPEN_MAX}
  710.  *    3    number of supplementary group id's    {NGROUPS_MAX}
  711.  *    4    max. number of processes per uid    {CHILD_MAX}
  712.  *
  713.  * unlimited values (e.g. CHILD_MAX) are returned as 0x7fffffffL
  714.  *
  715.  * See also Dpathconf() in dosdir.c.
  716.  */
  717.  
  718. long ARGS_ON_STACK
  719. s_ysconf(which)
  720.     int which;
  721. {
  722.     if (which == -1)
  723.         return 4;
  724.  
  725.     switch(which) {
  726.         case 0:
  727.             return UNLIMITED;
  728.         case 1:
  729.             return 126;
  730.         case 2:
  731.             return MAX_OPEN;
  732.         case 3:
  733.             return NGROUPS_MAX;
  734.         case 4:
  735.             return UNLIMITED;
  736.         default:
  737.             return EINVFN;
  738.     }
  739. }
  740.  
  741. /*
  742.  * Salert: send an ALERT message to the user, via the same mechanism
  743.  * the kernel does (i.e. u:\pipe\alert, if it's available
  744.  */
  745.  
  746. long ARGS_ON_STACK
  747. s_alert(str)
  748.     char *str;
  749. {
  750. /* how's this for confusing code? _ALERT tries to format the
  751.  * string as an alert box; if it fails, we let the full-fledged
  752.  * ALERT function (which will try _ALERT, and fail again)
  753.  * print the alert to the debugging device
  754.  */
  755.     if (_ALERT(str) == 0)
  756.         ALERT(str);
  757.     return 0;
  758. }
  759.  
  760. /*
  761.  * Suptime: get time in seconds since boot and current load averages from
  762.  * kernel.
  763.  */
  764.  
  765. #include "loadave.h"
  766.  
  767. long ARGS_ON_STACK
  768. s_uptime(cur_uptime, loadaverage)
  769.     unsigned long *cur_uptime;
  770.     unsigned long loadaverage[3];
  771. {
  772.     *cur_uptime = uptime;
  773.     loadaverage[0] = avenrun[0];
  774.     loadaverage[1] = avenrun[1];
  775.     loadaverage[2] = avenrun[2];
  776.  
  777.     return 0;
  778. }
  779.  
  780. /*
  781.  * routine for initializing DOS
  782.  *
  783.  * NOTE: before adding new functions, check the definition of
  784.  * DOS_MAX at the top of this file to make sure that there
  785.  * is room; if not, increase DOS_MAX.
  786.  */
  787.  
  788. void
  789. init_dos()
  790. {
  791. /* miscellaneous initialization goes here */
  792.  
  793. /* dos table initialization */
  794.     dos_tab[0x00] = p_term0;
  795.     dos_tab[0x01] = c_conin;
  796.     dos_tab[0x02] = c_conout;
  797.     dos_tab[0x03] = c_auxin;
  798.     dos_tab[0x04] = c_auxout;
  799.     dos_tab[0x05] = c_prnout;
  800.     dos_tab[0x06] = c_rawio;
  801.     dos_tab[0x07] = c_rawcin;
  802.     dos_tab[0x08] = c_necin;
  803.     dos_tab[0x09] = c_conws;
  804.     dos_tab[0x0a] = c_conrs;
  805.     dos_tab[0x0b] = c_conis;
  806.     dos_tab[0x0e] = d_setdrv;
  807.     dos_tab[0x10] = c_conos;
  808.     dos_tab[0x11] = c_prnos;
  809.     dos_tab[0x12] = c_auxis;
  810.     dos_tab[0x13] = c_auxos;
  811.     dos_tab[0x14] = m_addalt;
  812.     dos_tab[0x15] = s_realloc;
  813.     dos_tab[0x19] = d_getdrv;
  814.     dos_tab[0x1a] = f_setdta;
  815.     dos_tab[0x20] = s_uper;
  816.     dos_tab[0x2a] = t_getdate;
  817.     dos_tab[0x2b] = t_setdate;
  818.     dos_tab[0x2c] = t_gettime;
  819.     dos_tab[0x2d] = t_settime;
  820.     dos_tab[0x2f] = f_getdta;
  821.     dos_tab[0x30] = s_version;
  822.     dos_tab[0x31] = p_termres;
  823.     dos_tab[0x36] = d_free;
  824.     dos_tab[0x39] = d_create;
  825.     dos_tab[0x3a] = d_delete;
  826.     dos_tab[0x3b] = d_setpath;
  827.     dos_tab[0x3c] = f_create;
  828.     dos_tab[0x3d] = f_open;
  829.     dos_tab[0x3e] = f_close;
  830.     dos_tab[0x3f] = f_read;
  831.     dos_tab[0x40] = f_write;
  832.     dos_tab[0x41] = f_delete;
  833.     dos_tab[0x42] = f_seek;
  834.     dos_tab[0x43] = f_attrib;
  835.     dos_tab[0x44] = m_xalloc;
  836.     dos_tab[0x45] = f_dup;
  837.     dos_tab[0x46] = f_force;
  838.     dos_tab[0x47] = d_getpath;
  839.     dos_tab[0x48] = m_alloc;
  840.     dos_tab[0x49] = m_free;
  841.     dos_tab[0x4a] = m_shrink;
  842.     dos_tab[0x4b] = p_exec;
  843.     dos_tab[0x4c] = p_term;
  844.     dos_tab[0x4e] = f_sfirst;
  845.     dos_tab[0x4f] = f_snext;
  846.     dos_tab[0x56] = f_rename;
  847.     dos_tab[0x57] = f_datime;
  848.     dos_tab[0x5c] = f_lock;
  849.  
  850. /* MiNT extensions to GEMDOS */
  851.  
  852.     dos_tab[0xff] = s_yield;
  853.     dos_tab[0x100] = f_pipe;
  854.     dos_tab[0x104] = f_cntl;
  855.     dos_tab[0x105] = f_instat;
  856.     dos_tab[0x106] = f_outstat;
  857.     dos_tab[0x107] = f_getchar;
  858.     dos_tab[0x108] = f_putchar;
  859.     dos_tab[0x109] = p_wait;
  860.     dos_tab[0x10a] = p_nice;
  861.     dos_tab[0x10b] = p_getpid;
  862.     dos_tab[0x10c] = p_getppid;
  863.     dos_tab[0x10d] = p_getpgrp;
  864.     dos_tab[0x10e] = p_setpgrp;
  865.     dos_tab[0x10f] = p_getuid;
  866.     dos_tab[0x110] = p_setuid;
  867.     dos_tab[0x111] = p_kill;
  868.     dos_tab[0x112] = p_signal;
  869.     dos_tab[0x113] = p_vfork;
  870.     dos_tab[0x114] = p_getgid;
  871.     dos_tab[0x115] = p_setgid;
  872.  
  873.     dos_tab[0x116] = p_sigblock;
  874.     dos_tab[0x117] = p_sigsetmask;
  875.     dos_tab[0x118] = p_usrval;
  876.     dos_tab[0x119] = p_domain;
  877.     dos_tab[0x11a] = p_sigreturn;
  878.     dos_tab[0x11b] = p_fork;
  879.     dos_tab[0x11c] = p_wait3;
  880.     dos_tab[0x11d] = f_select;
  881.     dos_tab[0x11e] = p_rusage;
  882.     dos_tab[0x11f] = p_setlimit;
  883.     dos_tab[0x120] = t_alarm;
  884.     dos_tab[0x121] = p_pause;
  885.     dos_tab[0x122] = s_ysconf;
  886.     dos_tab[0x123] = p_sigpending;
  887.     dos_tab[0x124] = d_pathconf;
  888.     dos_tab[0x125] = p_msg;
  889.     dos_tab[0x126] = f_midipipe;
  890.     dos_tab[0x127] = p_renice;
  891.     dos_tab[0x128] = d_opendir;
  892.     dos_tab[0x129] = d_readdir;
  893.     dos_tab[0x12a] = d_rewind;
  894.     dos_tab[0x12b] = d_closedir;
  895.     dos_tab[0x12c] = f_xattr;
  896.     dos_tab[0x12d] = f_link;
  897.     dos_tab[0x12e] = f_symlink;
  898.     dos_tab[0x12f] = f_readlink;
  899.     dos_tab[0x130] = d_cntl;
  900.     dos_tab[0x131] = f_chown;
  901.     dos_tab[0x132] = f_chmod;
  902.     dos_tab[0x133] = p_umask;
  903.     dos_tab[0x134] = p_semaphore;
  904.     dos_tab[0x135] = d_lock;
  905.     dos_tab[0x136] = p_sigpause;
  906.     dos_tab[0x137] = p_sigaction;
  907.     dos_tab[0x138] = p_geteuid;
  908.     dos_tab[0x139] = p_getegid;
  909.     dos_tab[0x13a] = p_waitpid;
  910.     dos_tab[0x13b] = d_getcwd;
  911.     dos_tab[0x13c] = s_alert;
  912.     dos_tab[0x13d] = t_malarm;
  913.     dos_tab[0x13e] = p_sigintr;
  914.     dos_tab[0x13f] = s_uptime;
  915.     dos_tab[0x142] = d_xreaddir;
  916.     dos_tab[0x143] = p_seteuid;
  917.     dos_tab[0x144] = p_setegid;
  918.     dos_tab[0x145] = p_getauid;
  919.     dos_tab[0x146] = p_setauid;
  920.     dos_tab[0x147] = p_getgroups;
  921.     dos_tab[0x148] = p_setgroups;
  922.     dos_tab[0x149] = t_setitimer;
  923.  
  924.     /* 0x14a-0x151 reserved */
  925.  
  926.     dos_tab[0x152] = d_readlabel;
  927.     dos_tab[0x153] = d_writelabel;
  928. }
  929.